package com.allwees.bs.module.core.req.interceptor;

import com.allwees.bs.core.modelbase.branch.BranchUser;
import com.allwees.bs.core.modelbase.branch.BranchUserContext;
import com.allwees.bs.core.modelbase.req.Req;
import com.allwees.bs.core.modelbase.req.SmsVerifyCode;
import com.allwees.bs.core.modelbase.validate.Validatable;
import com.allwees.bs.module.core.rest.BaseApi;
import com.allwees.core.common.util.BeanUtil;
import com.allwees.sender.sms.SmsCodeVerifier;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * RestController拦截器
 *
 * @author yangylsky
 * @since 2019-09-23
 *
 */
@Aspect
@Component
public class RestInterceptor {
	@Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
	public void pointcut() {
	}

	@Around("pointcut()")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		bindUser();
		Object[] params = joinPoint.getArgs();
		for(Object param : params) {
			if(param == null){
				continue;
			}
			validateSmsVerifyCode(param);
			validateReq(param);
		}
		Object retObj = joinPoint.proceed();
		unbindUser();
		return retObj;
	}

	private void validateSmsVerifyCode(Object param) {
		if(SmsVerifyCode.class.isAssignableFrom(param.getClass())) {
			SmsVerifyCode smsReq = (SmsVerifyCode) param;
			Validatable.validate(smsReq.validateItems());
			SmsCodeVerifier verifier = BeanUtil.getBean(SmsCodeVerifier.class);
			verifier.verify(smsReq.getSmsType(), smsReq.getMobile(), smsReq.getVerifyCode());
		}
	}

	private void validateReq(Object param) {
		if(Req.class.isAssignableFrom(param.getClass())) {
			Req req = (Req) param;
			req.setBranchUser(BranchUserContext.getUser());
			req.validate();
		}
	}

	private void bindUser() {
		//Oauth2配置类在系统启动会进入此拦截器，因此不做强制登录验证
		BranchUser user = BaseApi.getCurrentUser(false);
		if(null != user) {
			BranchUserContext.setUser(user);
		}
	}

	private void unbindUser() {
		BranchUserContext.unsetUser();
	}
}